package com.linkoog.devtools.metadata.raw_index;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.linkoog.devtools.raw_index.core.PsiMethodRawFileIndex;
import com.linkoog.devtools.type.Type;
import com.linkoog.devtools.type.TypeParser;
import com.linkoog.devtools.type.javadoc.JavaDoc;
import com.linkoog.devtools.type.javadoc.JavaDocParser;
import com.linkoog.devtools.type.swagger.JavaSwaggerParser;
import com.linkoog.devtools.utils.VirtualFileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class MethodMetadataRawFileIndex extends PsiMethodRawFileIndex<MethodMetadata> {

    public static final Key<Set<PsiElement>> key = Key.create("DevTools.MethodMetadataRawFileIndex.Key");

    public static MethodMetadataRawFileIndex getInstance(Project project){
        return EXTENSION_POINT_NAME.findExtension(MethodMetadataRawFileIndex.class, project);
    }

    @Override
    public Key<Set<PsiElement>> getPsiElementKey() {
        return key;
    }

    @Override
    public File getCacheFile(Project project) throws IOException{
        return new File(project.getBasePath() + "/.idea/index-data/MetaMethod.idx");
    }

    @Override
    public Class<MethodMetadata> getValueClass(Project project) {
        return MethodMetadata.class;
    }

    @Override
    public MethodMetadata resolve(PsiMethod psiMethod) {
        final VirtualFile virtualFile = psiMethod.getContainingFile().getOriginalFile().getVirtualFile();
        final long timestamp = VirtualFileUtils.getTimestamp(virtualFile);
        MethodMetadata methodMetadata = new MethodMetadata(virtualFile.getUrl(), psiMethod.getTextOffset(), psiMethod.getName(),
                ()-> {
                    List<Type> paramTypes = new ArrayList<>();
                    PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
                    for (PsiParameter parameter : parameters) {
                        Type paramType = TypeParser.parse(parameter.getType());
                        paramTypes.add(paramType);
                    }
                    return paramTypes;
                },
                ()->TypeParser.parse(psiMethod.getReturnType())  );
        methodMetadata.initPsiElement(psiMethod.getProject(), psiMethod);
        methodMetadata.setJavaDocSupplier(() -> JavaDocParser.parse(psiMethod.getDocComment()));
        methodMetadata.setSwaggerCommentSupplier(() -> JavaSwaggerParser.parseMethod(psiMethod));
        methodMetadata.setTimestamp(timestamp);
        return methodMetadata;
    }


}
